import dayjs from 'dayjs'
import { Button, DatePicker, InputNumber, message, Popover, Tooltip } from 'antd'
import Icon, { DeleteOutlined, PlusOutlined } from '@ant-design/icons'

import { Texty } from '@/components/Texty'
import { filePick } from '@/utils/filePick'
import { disableFutureDate, disableFutureTime, fileValidate } from '@/utils/utils'
import { TCellParams } from './interface'
import { useBoundStore } from './store'
import FileIcon from '@/assets/icons/file.svg?react'
import styles from './styles.module.less'

/** 发生时间 */
export const OccurDateCell = ({ value, valueFormatted, data }: TCellParams<'occurDate'>) => {
  const editingRowData = useBoundStore(v => v.editingRowData)
  const setEditingRowData = useBoundStore(v => v.setEditingRowData)
  const draftRowData = data && data.publishId === editingRowData?.publishId ? editingRowData : null
  if (draftRowData) {
    return (
      <DatePicker
        className={styles.editingEle}
        allowClear={false}
        format="YYYY-MM-DD HH:mm:ss"
        showTime={{ format: 'HH:mm:ss' }}
        disabledDate={disableFutureDate}
        disabledTime={disableFutureTime}
        value={draftRowData.occurDate ? dayjs(draftRowData.occurDate) : undefined}
        onChange={(_, valStr) => setEditingRowData({ ...draftRowData, occurDate: `${valStr || ''}` })}
      />
    )
  }
  return valueFormatted ?? value ?? ''
}

/** 持续时间 */
export const KeepDateCell = ({ value, valueFormatted, data }: TCellParams<'keepDate'>) => {
  const editingRowData = useBoundStore(v => v.editingRowData)
  const setEditingRowData = useBoundStore(v => v.setEditingRowData)
  const draftRowData = data && data.publishId === editingRowData?.publishId ? editingRowData : null
  if (draftRowData) {
    return (
      <InputNumber
        className={styles.editingEle}
        min="0"
        precision={0}
        stringMode
        placeholder="请输入持续时间"
        suffix="h"
        value={draftRowData.keepDate}
        onChange={v => setEditingRowData({ ...draftRowData, keepDate: v || null })}
      />
    )
  }
  return valueFormatted ?? value ?? ''
}

/** 附件 */
export const FileListCell = ({ value, data }: TCellParams<'fileList'>) => {
  const editingRowData = useBoundStore(v => v.editingRowData)
  const setEditingRowData = useBoundStore(v => v.setEditingRowData)
  const draftRowData = data && data.publishId === editingRowData?.publishId ? editingRowData : null

  const renderFileList = (isEditing: boolean, files: Array<{ fileName: string; fileUrl: string | File }>) => {
    if (!isEditing && !files.length) return

    const fileIcon = <Icon className={styles.CellEdit_fileIcon} component={FileIcon} />

    return (
      <Popover
        destroyTooltipOnHide
        key={`${isEditing}${files.length > 0}`}
        content={
          files.length > (isEditing ? 0 : 1) && (
            <div className={styles.CellEdit_file}>
              {files.map(d => (
                <div key={d.fileName} className={styles.CellEdit_file_item}>
                  <span className={styles.CellEdit_file_item_file}>
                    {d.fileUrl instanceof File ? (
                      <Texty mouseEnterDelay={0.6} content={d.fileUrl.name}>
                        {fileIcon}
                        {d.fileUrl.name}
                      </Texty>
                    ) : (
                      <Texty mouseEnterDelay={0.6} content={d.fileName}>
                        <a target="_blank" rel="noreferrer" href={d.fileUrl}>
                          {fileIcon}
                          {d.fileName}
                        </a>
                      </Texty>
                    )}
                  </span>
                  {isEditing && (
                    <Tooltip title="移除">
                      <Button
                        className={styles.CellEdit_file_item_icon}
                        type="link"
                        danger
                        icon={<DeleteOutlined />}
                        onClick={() => {
                          const { fileList, draftFileList } = editingRowData!
                          setEditingRowData({
                            ...editingRowData!,
                            fileList: fileList?.filter(f => f.fileName !== d.fileName) ?? null,
                            draftFileList: draftFileList?.filter(f => f.fileName !== d.fileName) ?? null,
                          })
                        }}
                      />
                    </Tooltip>
                  )}
                </div>
              ))}
            </div>
          )
        }
      >
        {isEditing ? (
          <Button
            className={styles.editingEle}
            icon={<PlusOutlined />}
            onClick={() => {
              const accept = `${fileValidate.IMG_ACCEPT},${fileValidate.EXCEL_ACCEPT},${fileValidate.WORD_ACCEPT},${fileValidate.PDF_ACCEPT}`
              filePick({
                accept: accept,
                onFilePick: ([file]) => {
                  const errMsg = fileValidate(file, { accept, max: fileValidate.MAX })
                  if (errMsg) {
                    return void message.error(errMsg)
                  }
                  const { fileList, draftFileList } = editingRowData!
                  setEditingRowData({
                    ...editingRowData!,
                    fileList: fileList?.filter(f => f.fileName !== file.name) ?? null,
                    draftFileList: (draftFileList?.filter(f => f.fileName !== file.name) ?? []).concat({
                      fileName: file.name,
                      fileUrl: file,
                    }),
                  })
                  message.success('添加成功，发布时上传')
                },
              })
            }}
          >
            添加附件 ({files.length})
          </Button>
        ) : (
          <a target="_blank" rel="noreferrer" href={files[0].fileUrl as string}>
            {fileIcon}
            {files[0].fileName}
            {files.length > 1 && `(${files.length})`}
          </a>
        )}
      </Popover>
    )
  }

  if (draftRowData) {
    return renderFileList(true, [...(draftRowData.fileList || []), ...(draftRowData.draftFileList || [])])
  }
  return renderFileList(false, value || [])
}
